home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- ** % cc -o toverlay toverlay.c -lGL
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <GL/gl.h>
- #include <GL/glx.h>
- #include <X11/Xlib.h>
- #include <X11/keysym.h>
-
- #define DISPLAY_BOTH 0
- #define DISPLAY_NORMAL 1
- #define DISPLAY_OVERLAY 2
-
- static void
- drawSquare(float c)
- {
- glIndexf(c);
-
- glBegin(GL_QUADS);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(1.0, 0.0, 0.0);
- glVertex3f(1.0, 1.0, 0.0);
- glVertex3f(0.0, 1.0, 0.0);
- glEnd();
- }
-
- static void
- drawCheck(float c1, float c2)
- {
- int w = 4, h = 4;
- int i, j;
-
- for (j=0; j<h; ++j) {
- for (i=0; i<w; ++i) {
- glPushMatrix();
- glTranslatef((1.0/w) * i, (1.0/h) * j, 0.0);
- glScalef(1.0/w, 1.0/h, 1.0);
- if ((i & 1) ^ (j & 1)) {
- drawSquare(c1);
- } else {
- drawSquare(c2);
- }
- glPopMatrix();
- }
- }
- }
-
- static void
- usage(int argc, char **argv)
- {
- fprintf(stderr, "\n");
- fprintf(stderr, "usage: %s [options]\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, " OpenGL overlay plane rendering test\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " Options:\n");
- fprintf(stderr, " -nm just display normal plane window\n");
- fprintf(stderr, " -ov just display overlay plane window\n");
- fprintf(stderr, " -m mode display both windows according to mode:\n");
- fprintf(stderr, " 0 overlay is child of normal (default)\n");
- fprintf(stderr, " 1 both are children of root\n");
- fprintf(stderr, " 2 both are children of a child of root\n");
- fprintf(stderr, " -bindov bind opengl to overlay window first\n");
- fprintf(stderr, " -gl toggle opengl rendering\n");
- fprintf(stderr, " -a toggle animation\n");
- fprintf(stderr, "\n");
- }
-
- static Colormap
- buildColormap(Display *dpy, Window win, XVisualInfo *xvis)
- {
- Colormap cmap;
-
- if ((cmap = XCreateColormap(dpy, win, xvis->visual, AllocNone)) == None) {
- fprintf(stderr, "can't create colormap\n");
- exit(EXIT_FAILURE);
- }
-
- if (xvis->class == PseudoColor) {
- int mapSize = 1 << xvis->depth;
- int firstEntry = 0;
- int entry;
- unsigned long *pixels;
-
- pixels = (unsigned long *) calloc(mapSize, sizeof(unsigned long));
-
- if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize))
- {
- if (!XAllocColorCells(dpy, cmap, True, NULL, 0, pixels, mapSize-1))
- {
- fprintf(stderr, "can't alloc enough colormap entries\n");
- exit(EXIT_FAILURE);
- }
- firstEntry = 1;
- }
-
- for (entry=firstEntry; entry<mapSize; ++entry) {
- XColor xcol;
- int hue = entry % 8;
- short val = 0xffff;
-
- xcol.pixel = entry;
- xcol.red = (hue==1 || hue==5 || hue==6 || hue==7) ? val : 0;
- xcol.green = (hue==2 || hue==4 || hue==6 || hue==7) ? val : 0;
- xcol.blue = (hue==3 || hue==4 || hue==5 || hue==7) ? val : 0;
- xcol.flags = DoRed | DoGreen | DoBlue;
-
- XStoreColor(dpy, cmap, &xcol);
- }
-
- free((void *) pixels);
- }
-
- return cmap;
- }
-
- static void
- windopen(Display **dpy_ret, Window *win_ret,
- GLXContext *ctx_ret, int *visAttrs,
- const char *name, int w, int h)
- {
- static Display *dpy = NULL;
- int scr;
- Window root;
- XVisualInfo *xvis;
- GLXContext ctx;
- XSetWindowAttributes xswa;
- Colormap cmap;
- Window win;
- XEvent event;
-
- if (dpy == NULL) {
- if ((dpy = XOpenDisplay(NULL)) == NULL) {
- fprintf(stderr, "can't open display\n");
- exit(EXIT_FAILURE);
- }
- }
- scr = DefaultScreen(dpy);
- root = RootWindow(dpy, scr);
-
- if ((xvis = glXChooseVisual(dpy, scr, visAttrs)) == NULL) {
- fprintf(stderr, "can't find visual\n");
- exit(EXIT_FAILURE);
- }
-
- if ((ctx = glXCreateContext(dpy, xvis, NULL, True)) == None) {
- fprintf(stderr, "can't create context\n");
- exit(EXIT_FAILURE);
- }
-
- xswa.colormap = buildColormap(dpy, root, xvis);
- xswa.background_pixel = 0;
- xswa.border_pixel = 0;
- xswa.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask;
- win = XCreateWindow(dpy, root, 0, 0, w, h, 0,
- xvis->depth, InputOutput, xvis->visual,
- CWColormap | CWBackPixel | CWBorderPixel | CWEventMask,
- &xswa);
-
- if (name) {
- XStoreName(dpy, win, name);
- }
-
- *dpy_ret = dpy;
- *win_ret = win;
- *ctx_ret = ctx;
- }
-
- static Bool
- waitForNotify(Display *dpy, XEvent *event, XPointer arg)
- {
- return (event->type == MapNotify && event->xmap.window == (Window) arg);
- }
-
- static int normalVisAttrs[] = {
- GLX_LEVEL, 0,
- GLX_BUFFER_SIZE, 4,
- None
- };
-
- static int overlayVisAttrs[] = {
- GLX_LEVEL, 1,
- GLX_BUFFER_SIZE, 2,
- None
- };
-
- int
- main(int argc, char **argv)
- {
- int mode = DISPLAY_BOTH;
- int useGL = 1;
- int animate = 1;
- int manageTogether = 1;
- int manageUsingParent = 0;
- int delayBind = 0;
- int width = 300, height = 300;
- int ovWidth = width, ovHeight = height;
- float spin0 = 0.0, spinRate0 = 1.0;
- float spin1 = 45.0, spinRate1 = -1.0;
- int normInit = 0;
- int overInit = 0;
- Display *dpy;
- Window parentWin = None;
- GLXContext parentCtx = None;
- Window normWin = None;
- GLXContext normCtx = None;
- Window overWin = None;
- GLXContext overCtx = None;
- XEvent event;
- int i;
-
- for (i=1; i<argc; ++i) {
- if (!strcmp("-nm", argv[i]))
- {
- mode = DISPLAY_NORMAL;
- }
- else if (!strcmp("-ov", argv[i]))
- {
- mode = DISPLAY_OVERLAY;
- }
- else if (!strcmp("-m", argv[i]) && (i+1 < argc))
- {
- mode = DISPLAY_BOTH;
- switch (atoi(argv[++i])) {
- case 0:
- manageTogether = 1; manageUsingParent = 0;
- break;
- case 1:
- manageTogether = 0; manageUsingParent = 0;
- break;
- case 2:
- manageTogether = 1; manageUsingParent = 1;
- break;
- default:
- usage(argc, argv);
- exit(EXIT_FAILURE);
- break;
- }
- }
- else if (!strcmp("-bindov", argv[i]))
- {
- delayBind = 1;
- }
- else if (!strcmp("-gl", argv[i]))
- {
- useGL = !useGL;
- }
- else if (!strcmp("-a", argv[i]))
- {
- animate = !animate;
- }
- else
- {
- usage(argc, argv);
- exit(EXIT_FAILURE);
- }
- }
-
- if (mode == DISPLAY_BOTH && manageUsingParent) {
- windopen(&dpy, &parentWin, &parentCtx,
- normalVisAttrs, "overlay test", width, height);
-
- XMapWindow(dpy, parentWin);
- XIfEvent(dpy, &event, waitForNotify, (XPointer) parentWin);
- }
-
- if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
- windopen(&dpy, &normWin, &normCtx,
- normalVisAttrs, "overlay test", width, height);
-
- if (mode == DISPLAY_BOTH && manageUsingParent) {
- XReparentWindow(dpy, normWin, parentWin, 0, 0);
- }
-
- XMapWindow(dpy, normWin);
- XIfEvent(dpy, &event, waitForNotify, (XPointer) normWin);
-
- if (useGL && !delayBind) {
- glXMakeCurrent(dpy, normWin, normCtx);
- }
- }
-
- if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
- windopen(&dpy, &overWin, &overCtx,
- overlayVisAttrs, "overlay test", ovWidth, ovHeight);
-
- if (mode == DISPLAY_BOTH && manageTogether) {
- if (manageUsingParent) {
- XReparentWindow(dpy, overWin, parentWin, 0, 0);
- } else {
- XReparentWindow(dpy, overWin, normWin, 0, 0);
- }
- }
-
- XMapWindow(dpy, overWin);
- XIfEvent(dpy, &event, waitForNotify, (XPointer) overWin);
-
- if (useGL && !delayBind) {
- glXMakeCurrent(dpy, overWin, overCtx);
- }
- }
-
- if (mode == DISPLAY_BOTH && manageTogether) {
- Window winList[3];
-
- if (manageUsingParent) {
- winList[0] = overWin;
- winList[1] = normWin;
- winList[2] = parentWin;
- XSetWMColormapWindows(dpy, parentWin, winList, 3);
- } else {
- winList[0] = overWin;
- winList[1] = normWin;
- XSetWMColormapWindows(dpy, normWin, winList, 2);
- }
- }
-
- while (1) {
- int reconfigure = 0;
- int redraw = 0;
-
- if (XPending(dpy)) {
- KeySym ks;
-
- XNextEvent(dpy, &event);
- switch (event.type) {
- case KeyPress:
- XLookupString(&event.xkey, NULL, 0, &ks, NULL);
- if (ks == XK_Escape) {
- exit(EXIT_SUCCESS);
- }
- break;
- case Expose:
- redraw = 1;
- break;
- case ConfigureNotify:
- if (mode == DISPLAY_BOTH && manageTogether) {
- if (manageUsingParent &&
- event.xconfigure.window == parentWin)
- {
- width = ovWidth = event.xconfigure.width;
- height = ovHeight = event.xconfigure.height;
- XResizeWindow(dpy, normWin, width, height);
- XResizeWindow(dpy, overWin, ovWidth, ovHeight);
- }
- if (!manageUsingParent &&
- event.xconfigure.window == normWin)
- {
- width = ovWidth = event.xconfigure.width;
- height = ovHeight = event.xconfigure.height;
- XResizeWindow(dpy, overWin, ovWidth, ovHeight);
- }
- } else {
- if (event.xconfigure.window == normWin) {
- width = event.xconfigure.width;
- height = event.xconfigure.height;
- }
- if (event.xconfigure.window == overWin) {
- ovWidth = event.xconfigure.width;
- ovHeight = event.xconfigure.height;
- }
- }
- reconfigure = 1;
- redraw = 1;
- break;
- default:
- break;
- }
- }
-
- if (animate) {
- spin0 += spinRate0;
- if (spin0 > 360.0) spin0 -= 360.0;
-
- spin1 += spinRate1;
- if (spin1 > 360.0) spin1 -= 360.0;
-
- redraw = 1;
- }
-
- if (useGL) {
- if (mode == DISPLAY_BOTH || mode == DISPLAY_OVERLAY) {
- if (mode == DISPLAY_BOTH || !overInit) {
- glXMakeCurrent(dpy, overWin, overCtx);
-
- if (!overInit) {
- glMatrixMode(GL_PROJECTION);
- glOrtho(-1, 1, -1, 1, 1, 3);
- glMatrixMode(GL_MODELVIEW);
- glTranslatef(0.0, 0.0, -2.0);
- glLineWidth(4.0);
- overInit = 1;
- }
- }
-
- if (reconfigure) {
- glViewport(0, 0, ovWidth, ovHeight);
- }
-
- if (redraw) {
- glClear(GL_COLOR_BUFFER_BIT);
-
- glPushMatrix();
- glRotatef(spin1, 0, 0, 1);
- glScalef(1.25, 1.25, 1.0);
- glTranslatef(-0.5, -0.5, 0.0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- drawCheck(1, 2);
- glPopMatrix();
- }
- }
-
- if (mode == DISPLAY_BOTH || mode == DISPLAY_NORMAL) {
- if (mode == DISPLAY_BOTH || !normInit) {
- glXMakeCurrent(dpy, normWin, normCtx);
-
- if (!normInit) {
- glMatrixMode(GL_PROJECTION);
- glOrtho(-1, 1, -1, 1, 1, 3);
- glMatrixMode(GL_MODELVIEW);
- glTranslatef(0.0, 0.0, -2.0);
- normInit = 1;
- }
- }
-
- if (reconfigure) {
- glViewport(0, 0, width, height);
- }
-
- if (redraw) {
- glClear(GL_COLOR_BUFFER_BIT);
-
- glPushMatrix();
- glRotatef(spin0, 0, 0, 1);
- glScalef(1.25, 1.25, 1.0);
- glTranslatef(-0.5, -0.5, 0.0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- drawCheck(3, 4);
- glPopMatrix();
- }
- }
- }
- }
- }
-